//
// Created by wujehy on 2020/8/3.
//

#include "BusinessManager.h"
#include "Mod/BusinessBase.h"
#include "Mod/TestMod.h"
#include <handy/handy.h>
#include <Mod/IoTMod.h>
#include "Network.pb.h"
#include "Mod/Test2Mod.h"
#include "Mod/AuthMod.h"
#include "GeeJoan/NetWorkPackage.pb.h"
#include "GeeJoan/ErrorModule.pb.h"
#include "Context/TaskContext.h"
#include "NetWorkWarpper.h"

using handy::Logger;

void BusinessManager::init()
{
    // 初始化
    m_listernerManager.init();
    daoManager.init();
    // 注册
    registerMod();
}

void BusinessManager::registerMod()
{
    // 注册 模块
    auto *testMod = new TestMod;
    testMod->context = netWorkWarpper;
    auto pt1 = m_mod_map.insert( {testMod->type(), testMod} );
    if (!pt1.second)
    {
        delete testMod;
    }

    auto *test2Mod = new Test2Mod;
    test2Mod->context = netWorkWarpper;
    auto pt2 = m_mod_map.insert( {test2Mod->type(), test2Mod} );
    if (!pt1.second)
    {
        delete testMod;
    }

    auto *authMod = new AuthMod;
    authMod->context = netWorkWarpper;
    authMod->setBusinessManager( this );
    auto pt3 = m_mod_map.insert( {authMod->type(), authMod} );
    if (!pt3.second)
    {
        delete authMod;
    }

    auto *iotMod = new IoTMod;
    iotMod->context = netWorkWarpper;
    iotMod->setBusinessManager( this );
    auto pt4 = m_mod_map.insert( {iotMod->type(), iotMod} );
    if (!pt4.second)
    {
        delete iotMod;
    }

}

ManagerBase::Type BusinessManager::type()
{
    return ManagerBase::ManagerType_Business;
}

BusinessManager::~BusinessManager()
{
    fprintf( stderr, "delete BusinessManager \n" );

    for (auto b : m_mod_map)
    {
        delete b.second;
    }
}

BusinessManager::BusinessManager()
{
    fprintf( stderr, "init BusinessManager \n" );
}

void BusinessManager::callListerner(int type)
{
    m_listernerManager.callEvent( type );
}

ContextManager *BusinessManager::getContextManager()
{
    return &contextManager;
}

int BusinessManager::route(int64_t tcpid, GeeJoan::Protocol::NetWork::NetWorkPackageRequest *netWorkPacket)
{
    info( " BusinessManager::route type %d  , tcpid %ld ", netWorkPacket->type_sub(), tcpid );
    // 将当前包的基本信息 打包进 上下文 管理器
    TaskContext *task = new TaskContext;
    task->tcpid = tcpid;
    task->type_mod = netWorkPacket->type_m();
    task->type_sub = netWorkPacket->type_sub();
    int taskid;
    contextManager.add( taskid, task );
    // 找到 该网络包的 模块类型 进行 网络分包
    auto find = m_mod_map.find( netWorkPacket->type_m());
    if (find != m_mod_map.end())
    {
        // 将上下文 任务id 传递 过去  , 进行 子模块业务处理
        int ret = find->second->depackage( taskid, netWorkPacket->type_sub(), (void *) netWorkPacket->body().c_str(),
                                           netWorkPacket->body().length(),
                                           nullptr );
        if (ret == -2)
        {
            // 返回 -2 类型 则为止处理 外部释放 任务
            contextManager.remove( taskid );
        }
    }
    // 处理完成 内部管理 网路包 释放
    delete netWorkPacket;
    return 0;
}

void BusinessManager::setNetWorkWarpper(NetWorkWarpper *netWorkWarpper)
{
    BusinessManager::netWorkWarpper = netWorkWarpper;
}

int BusinessManager::call500(int taskid, std::string errmsg)
{
    using namespace GeeJoan::Protocol::NetWork;
    using namespace GeeJoan::Protocol::Error;
    auto taskData = contextManager.get_unique_ptr<TaskContext>( taskid, 1 );

    NetWorkPackageRespose respose;
    ErrorMessage errorMessage;
    errorMessage.set_errmsg( errmsg );
    respose.set_taskid( taskData->c_taskid );
    respose.set_type_sub( taskData->type_sub );
    respose.set_type_m( NetWorkPackageModel( taskData->type_mod ));
    respose.set_code( 500 );
    respose.set_body( errorMessage.SerializeAsString());

    auto conn = netWorkWarpper->m_id_client_map[taskData->tcpid];
    conn->send( respose.SerializeAsString());

    return 0;
}

int BusinessManager::call200(int taskid, std::string &body)
{
    using namespace GeeJoan::Protocol::NetWork;
    auto taskData = contextManager.get_unique_ptr<TaskContext>( taskid, 1 );
    NetWorkPackageRespose respose;
    respose.set_taskid( taskData->c_taskid );
    respose.set_type_sub( taskData->type_sub );
    respose.set_type_m( NetWorkPackageModel( taskData->type_mod ));
    respose.set_code( 200 );
    respose.set_body( body );
//    context->con->send( respose.SerializeAsString());
//    auto  conn = netWorkWarpper->m_id_client_map[taskData->tcpid];
    auto find = netWorkWarpper->m_id_client_map.find( taskData->tcpid );
    if (find != netWorkWarpper->m_id_client_map.end())
    {
        std::string outData;
        respose.SerializeToString( &outData );
        find->second->send( outData );
    }

    return 0;
}

int BusinessManager::call401(int taskid)
{
    using namespace GeeJoan::Protocol::NetWork;
    auto taskData = contextManager.get_unique_ptr<TaskContext>( taskid, 1 );
    NetWorkPackageRespose respose;
    respose.set_taskid( taskData->c_taskid );
    respose.set_type_sub( taskData->type_sub );
    respose.set_type_m( NetWorkPackageModel( taskData->type_mod ));
    respose.set_code( 401 );
    respose.set_body( "unKnow" );
    auto conn = netWorkWarpper->m_id_client_map[taskData->tcpid];
    conn->send( respose.SerializeAsString());
    return 0;
}

DaoManager *BusinessManager::getDaoManager()
{
    return &daoManager;
}

NetWorkWarpper *BusinessManager::getNetWorkWarpper() const
{
    return netWorkWarpper;
}

void BusinessManager::init_finished()
{
    // 触发所有 所管理的模块的 初始化完成监听器
    m_listernerManager.init_finished();
    contextManager.init_finished();
    daoManager.init_finished();

    for (auto m : m_mod_map)
    {
        m.second->init_finished();
    }


}
